/* ========================================
 *
 * Copyright YOUR COMPANY, THE YEAR
 * All Rights Reserved
 * UNPUBLISHED, LICENSED SOFTWARE.
 *
 * CONFIDENTIAL AND PROPRIETARY INFORMATION
 * WHICH IS THE PROPERTY OF your company.
 *
 * ========================================
*/

#include "beachday.h"

#define LCD_REFRESH_FREQ                        (10) // Hz
#define LCD_REFRESH_DELAY   MS(TICK_FREQ / LCD_REFRESH_FREQ)
#define LCD_MENU_X          (10)
#define LCD_MENU_Y          (DISPLAYHEIGHT - 10)

#define STRDEF(s)       s, sizeof(s)

// example character
//  {0b11111,
//   0b00001,
//   0b00010,
//   0b00100,
//   0b01000,
//   0b10000,
//   0b10000}

void printChar(char ch, uint16_t col, uint16_t row, uint32_t color)
{
    uint32_t i, j, c;
    
    for(i = 0; i < 7; i++)
    {
        c = GetChar((uint8)ch, i);
        
        for(j = 0; j < 5; j++)
        {
            if(c & (1 << j))
            {
                gfx_drawPixel(col + (4-j), row + i, color);
            }
        }
    }
}

void printLine(char* str, uint8_t len, uint16_t x, uint16_t y, uint32_t color)
{
    uint32_t i;
    
    for(i = 0; i < len; i++)
    {
        if((x > DISPLAYWIDTH) || (y > DISPLAYHEIGHT))
        {
            return;
        }
        
        printChar(*str++, x + (i * 8), y, color);
    }
}

uint32_t ServLCD( void )
{
    static uint32_t st = LCD_ST_INIT, Stamp, mode = SYS_MODE_COUNT, rnd_a = 12345, rnd_b = 34567;
    uint32_t x, y, a = 0, b = 0, c = 0;
    
    switch(st)
    {
        case LCD_ST_INIT:
            if(GetState(SSD1306) == SSD1306_ST_IDLE)
            {   
                display_clear();
                Stamp = GetTick();
                st = LCD_ST_IDLE;
            }
            break;
        case LCD_ST_IDLE:
            
            if(GetTick() - Stamp >= LCD_REFRESH_DELAY)
            {
                switch(mode) // every refresh
                {
                    case SYS_MODE_BATTERY:
                        x = DISPLAYWIDTH - (4 * 8) - 8;
                        y = 20;
                        gfx_fillRect(x, y - 2, 4 * 8, 10, BLACK);
                        c = GetADC(ADC_CH_BATTERY);
                        a = c / 1000;
                        b = (c / 100) - (10 * a);
                        c = (c / 10) - (100 * a) - (10 * b);
                        printChar((a > 9) ? a + 0x37 : a + 0x30, x, y, WHITE);
                        printChar('.', x + 8, y, WHITE);
                        printChar((b > 9) ? b + 0x37 : b + 0x30, x + 16, y, WHITE);
                        printChar((c > 9) ? c + 0x37 : c + 0x30, x + 24, y, WHITE);
                        
                        break;
                    case SYS_MODE_TVBGONE:
                        x = DISPLAYWIDTH - (4 * 8) - 8;
                        y = 20;
                        gfx_fillRect(x, y - 2, 4 * 8, 10, BLACK);
                        c = GetIRCode();
                        a = c / 100;
                        b = (c / 10) - (10 * a);
                        c = (c) - (100 * a) - (10 * b);
                        printChar((a > 9) ? a + 0x37 : a + 0x30, x, y, WHITE);
                        printChar((b > 9) ? b + 0x37 : b + 0x30, x + 8, y, WHITE);
                        printChar((c > 9) ? c + 0x37 : c + 0x30, x + 16, y, WHITE);
                        
                        break;
                    case SYS_MODE_MQ303:
                        x = 10;
                        y = 2;
                        gfx_fillRect(x, y - 2, 4 * 8, 10, BLACK);
                        (GetState(MQ303) == MQ303_ST_MAINT) ? printLine(STRDEF("HEAT"), x, y, WHITE) : printLine(STRDEF("READ"), x, y, WHITE);
                        
                        x = DISPLAYWIDTH - (4 * 8) - 8;
                        y = 20;
                        gfx_fillRect(x, y - 2, 4 * 8, 10, BLACK);
                        c = GetADC(ADC_CH_SUPPLY);
                        a = c / 1000;
                        b = (c / 100) - (10 * a);
                        c = (c / 10) - (100 * a) - (10 * b);
                        printChar((a > 9) ? a + 0x37 : a + 0x30, x, y, WHITE);
                        printChar('.', x + 8, y, WHITE);
                        printChar((b > 9) ? b + 0x37 : b + 0x30, x + 16, y, WHITE);
                        printChar((c > 9) ? c + 0x37 : c + 0x30, x + 24, y, WHITE);
                        
                        x = DISPLAYWIDTH - (4 * 8) - 8;
                        y = 30;
                        gfx_fillRect(x, y - 2, 4 * 8, 10, BLACK);
                        c = GetADC(ADC_CH_SENSOR);
                        a = c / 1000;
                        b = (c / 100) - (10 * a);
                        c = (c / 10) - (100 * a) - (10 * b);
                        printChar((a > 9) ? a + 0x37 : a + 0x30, x, y, WHITE);
                        printChar('.', x + 8, y, WHITE);
                        printChar((b > 9) ? b + 0x37 : b + 0x30, x + 16, y, WHITE);
                        printChar((c > 9) ? c + 0x37 : c + 0x30, x + 24, y, WHITE);
                        
                        break;

    #ifdef CY_BLE_CYBLE_H
                    case SYS_MODE_SYSTEM:
                        gfx_fillRect(30, 28, 32, 10, BLACK);
                        c = GetTick() / TICK_FREQ;
                        a = c / 100;
                        b = (c / 10) - (10 * a);
                        c = (c) - (100 * a) - (10 * b);
                        printChar((a > 9) ? a + 0x37 : a + 0x30, 30, 30, WHITE);
                        printChar((b > 9) ? b + 0x37 : b + 0x30, 38, 30, WHITE);
                        printChar((c > 9) ? c + 0x37 : c + 0x30, 46, 30, WHITE);
                        
                        break;
    #endif
    
                    case SYS_MODE_DISPLAY:
                        gfx_drawCircle(rnd_a % 127, rnd_b % 47 + 16, 4, BLACK);
                        
                        a=rnd_a>>8;
                        b=rnd_a&0xFF;
                        a=a*18273+b;
                        b=b*29379+a;
                        rnd_a=((a&0xFF)<<8)|(b&0xFF);
                        
                        a=rnd_b>>8;
                        b=rnd_b&0xFF;
                        a=a*18273+b;
                        b=b*29379+a;
                        rnd_b=((a&0xFF)<<8)|(b&0xFF);
                        
                        gfx_drawCircle(rnd_a % 127, rnd_b % 47 + 16, 4, WHITE);
                        
                        break;
                    case SYS_MODE_INPUT:
                        x = DISPLAYWIDTH - (5 * 8) - 8;
                        y = 3;
                        gfx_fillRect(x, y - 2, 5 * 8, 30, BLACK);
            
                        (GetCSProxState()) ? display_invert(TRUE) : display_invert(FALSE);
                        if(Enter_Read() == GPIO_LOW) printLine(STRDEF("ENTER"), x, y, WHITE);
                        if(Right_Read() == GPIO_LOW) printLine(STRDEF("RIGHT"), x, y + 10, WHITE);
                        if(Left_Read() == GPIO_LOW) printLine(STRDEF("LEFT "), x, y + 20, WHITE);
                        x = 8;
                        gfx_fillRect(x, y - 2, 5 * 8, 30, BLACK);
                        if(Up_Read() == GPIO_LOW) printLine(STRDEF("UP   "), x, y + 10, WHITE);
                        if(Down_Read() == GPIO_LOW) printLine(STRDEF("DOWN "), x, y + 20, WHITE);
                        
                        break;
                }
                
                if(mode != GetState(SYS)) // only once when mode changes
                {
                    mode = GetState(SYS);
                    
                    display_clear();
                    
                    switch(mode)
                    {
                        case SYS_MODE_BATTERY:
                            printLine(STRDEF("Battery ADC"), LCD_MENU_X, LCD_MENU_Y, WHITE);
                            printLine(STRDEF("Battery:"), 20, 20, WHITE);
                            
                            break;
                        case SYS_MODE_DISPLAY:
                            printLine(STRDEF("Display"), LCD_MENU_X, LCD_MENU_Y, WHITE);
                            
                            break;
                        case SYS_MODE_INPUT:
                            printLine(STRDEF("Input"), LCD_MENU_X, LCD_MENU_Y, WHITE);
                            
                            break;
                        case SYS_MODE_TVBGONE:
                            printLine(STRDEF("TV B Gone"), LCD_MENU_X, LCD_MENU_Y, WHITE);
                            printLine(STRDEF("Code Id:"), 20, 20, WHITE);
                            
                            break;
                            
    #ifdef CY_BLE_CYBLE_H
                        case SYS_MODE_SYSTEM:
                            printLine(STRDEF("System"), LCD_MENU_X, LCD_MENU_Y, WHITE);
                            printLine(STRDEF("Press enter to"), 10, 10, WHITE);
                            printLine(STRDEF("enter BSL"), 10, 20, WHITE);
                            
                            break;
    #endif
                            
                        case SYS_MODE_MQ303:
                            printLine(STRDEF("MQ303"), LCD_MENU_X, LCD_MENU_Y, WHITE);
                            printLine(STRDEF("Supply:"), 20, 20, WHITE);
                            printLine(STRDEF("Reading:"), 20, 30, WHITE);
                            break;
                    }
                }
                
                Stamp = GetTick();
            }
            break;
    }
    
    return st;
}




/* [] END OF FILE */
